public class test {
    //leetcode 1567.乘积为正数的最长子数组长度
    class Solution {
        // 解法1. 滑动窗口
        public int getMaxLen1(int[] nums) {
            int n = nums.length;
            int right = 0;
            // left表示遇到[0]或[结尾]的最靠前位置
            int left = 0;
            // first表示第一次遇到的负数
            int first = -1;
            // max用于记录乘积为正数的最大子数组长度
            int max = 0;
            // cur用于记录[left,right]中负数的个数
            int cur = 0;
            while (right < n) {
                if (nums[right] < 0) {
                    cur++;
                    if (first < 0) {
                        first = right;
                    }
                } else if (nums[right] == 0) {
                    cur = 0;
                    first = -1;
                    left = right + 1;
                }
                if (cur % 2 == 0) {
                    max = Math.max(right - left + 1, max);
                } else if (first >= 0) {
                    max = Math.max(right - first, max);
                }
                right++;
            }
            return max;
        }

        // 解法2. 动态规划
        public int getMaxLen(int[] nums) {
            // 1. 创建dp[]表
            int n = nums.length;
            int max = 0;
            // f[i]代表此时数组中最长子数组的长度
            int[] f = new int[n];
            // g[i]代表[值为负]的最长子数组长度
            int[] g = new int[n];
            // 2. 初始化
            if (nums[0] > 0) {
                max++;
                f[0]++;
            } else if (nums[0] < 0) {
                g[0]++;
            }
            // 3. 填表
            for (int i = 1; i < n; i++) {
                if (nums[i] > 0) {
                    f[i] = f[i - 1] + 1;
                    // 如果g[i - 1] == 0,则此时不存在负数,无法获得负数,不修改.
                    g[i] = g[i - 1] == 0 ? 0 : g[i - 1] + 1;
                } else if (nums[i] < 0) {
                    // 如果g[i - 1] == 0,则此时不存在负数,无法获得正数,不修改.
                    f[i] = g[i - 1] == 0 ? 0 : g[i - 1] + 1;
                    g[i] = f[i - 1] + 1;
                } else {
                    f[i] = 0;
                    g[i] = 0;
                }
                max = Math.max(max, f[i]);
            }
            // 4. 返回值
            return max;
        }
    }
    //leetcode 413.等差数列划分
    class Solution {
        // 解法1. 计数
        public int numberOfArithmeticSlices1(int[] nums) {
            int n = nums.length;
            if (n < 3) {
                return 0;
            }
            int count1 = 0; // 用于记录总的等差数列个数
            int count2 = 0; // 用于记录当前等差数列个数
            for (int i = 2; i < n; i++) {
                // 判断当前元素及其前两个元素,是否组成等差数列
                if (nums[i] - nums[i - 1] == nums[i - 1] - nums[i - 2]) {
                    count2++;
                    count1 += count2;
                } else {
                    count2 = 0;
                }
            }
            return count1;
        }

        // 解法2. 动态规划
        public int numberOfArithmeticSlices(int[] nums) {
            // 1. 创建dp[]表
            int n = nums.length;
            if (n < 3) {
                return 0;
            }
            int[] dp = new int[n];
            // 2. 初始化
            int sum = 0;
            // 3. 填表
            for (int i = 2; i < n; i++) {
                if (nums[i] - nums[i - 1] == nums[i - 1] - nums[i - 2]) {
                    dp[i] = dp[i - 1] + 1;
                } else {
                    dp[i] = 0;
                }
                sum += dp[i];
            }
            // 4. 返回值
            return sum;
        }
    }
}
